<?php
/**
 * This file holds the cModel
 *
 * @author Xander Hoogland <home@xanland.nl>
 * @package default
 */

/**
 * A model for easy databaseconnection and such.
 *
 * @author Xander Hoogland <home@xanland.nl>
 * @package default
 */
class cModel
{
	/**
	 * Id from the row to get
	 *
	 * @access private
	 * @var integer
	 */
	private $_sId;

	/**
	 * The name of the column for $_sId
	 *
	 * @access private
	 * @var string
	 */
	private $_sIdColumn;

	/**
	 * The table where to get the data from
	 *
	 * @access private
	 * @var string
	 */
	private $_sTable;

	/**
	 * The data of the row
	 *
	 * @access private
	 * @var array
	 */
	private $_aData;

	/**
	 * The connection with the database via PDO
	 *
	 * @access private
	 * @var object
	 */
	private $_pPDO;

	/**
	 * Constructor for defining some settings
	 *
	 * @global object $pPDO
	 * @param string $sId
	 * @param string $sIdColumn
	 * @param string $sTable
	 */
	public function __construct ( $sTable, $sIdColumn = 'id', $sId = NULL )
	{
		global $pPDO;

		$this -> _sTable = $sTable;

		$this -> _pPDO = $pPDO;

		$this -> _sIdColumn = $sIdColumn;

		$this -> _sId = $sId;
		//echo $this -> _sId;

		if ($this -> _sId !== NULL )
		{
			$this -> getData ();
		}
	}

	/**
	 * Get all the data from the table specified by
	 * the id
	 *
	 * @return boolean
	 */
	public function getData ()
	{
		$sQuery = "SELECT * FROM `" . mysql_real_escape_string ($this -> _sTable) . "` WHERE `" . mysql_real_escape_string ( $this -> _sIdColumn ) . "` = :sId;";
		try
		{
			$oStmt = $this -> _pPDO -> prepare ($sQuery);
			$oStmt -> bindParam (':sId', $this -> _sId, PDO::PARAM_STR);
			$oStmt -> execute ();
			for ($i = 0; $i < $oStmt -> columnCount(); $i++)
			{
				$aColumnInfo = $oStmt -> getColumnMeta ($i);
				$sColumnName = $aColumnInfo ['name'];
				$oStmt -> bindColumn ($sColumnName, $this -> _aData [$sColumnName]);
			}

			if ($oStmt -> fetch (PDO::FETCH_BOUND))
			{
				return true;
			}
			else
			{
				return false;
			}
		}
		catch (PDOException $e)
		{
			ePDOException :: writeMessage ($e);
			return false;
		}
	}

	/**
	 * Also set the changed data and update the table
	 *
	 * @return boolean
	 */
	public function save ()
	{
		foreach ($this -> _aData as $sVarName => $sVarValue)
		{
			//if ($sVarValue == '') echo '\'' . $sVarValue . '\''; continue;

			if ($this -> _sId === NULL )
			{
				$sQuery = "INSERT INTO `" . mysql_real_escape_string ( $this -> _sTable ) . "` (`" . mysql_real_escape_string ( $sVarName ) . "`) VALUES (:sVarValue);";
			}
			else
			{
				$sQuery = "UPDATE `" . mysql_real_escape_string ( $this -> _sTable ) . "` SET `" . mysql_real_escape_string ( $sVarName ) . "` = :sVarValue WHERE `" . mysql_real_escape_string ( $this -> _sIdColumn ) . "` = :sId;";
			}

			try
			{
				$oStmt = $this -> _pPDO -> prepare ($sQuery);
				$oStmt -> bindParam (':sVarValue', $sVarValue);
				if ($this -> _sId !== NULL)
				{
					$oStmt -> bindParam (':sId', $this -> _sId);
				}

				if ($oStmt -> execute () && $this -> _sId === NULL)
				{
					$this -> __construct ($this -> _sTable, $this -> _sIdColumn, $this -> _pPDO -> lastInsertId());
				}
				elseif ($oStmt -> execute ())
				{
					//
				}
				else
				{
					return false;
				}
			}
			catch (PDOException $e)
			{
				ePDOException :: writeMessage ($e);
				return false;
			}
		}
	}

	/**
	 * Getter for the data before doing setData()
	 *
	 * @param string $sVarName
	 * @return mixed
	 */
	public function __get ( $sVarName )
	{
		if (isset ( $sVarName ))
		{
			return $this -> _aData [ $sVarName ];
		}
	}

	/**
	 * Setter for the data before doing setData()
	 *
	 * @param string $sVarName
	 * @param mixed $sVarValue
	 */
	public function __set ( $sVarName, $sVarValue )
	{
		$this -> _aData [ $sVarName ] = $sVarValue;

		if ($this -> _sId === NULL )
		{
			$this -> save ();
		}
	}

	public function getAll ()
	{
		$aModels = array ();

		$sQuery = "SELECT * FROM `" . mysql_real_escape_string ($this -> _sTable) . "`;";
		try
		{
			$oStmt = $this -> _pPDO -> prepare ($sQuery);
			$oStmt -> execute ();

			foreach ($oStmt -> fetchAll (PDO :: FETCH_ASSOC) as $aRow)
			{
				$aModels[] = new cModel ($this -> _sTable, $this -> _sIdColumn, $aRow [ $this -> _sIdColumn ] );
			}
		}
		catch (PDOException $e)
		{
			ePDOException :: writeMessage ($e);
		}

		return $aModels;
	}
}